package com.dailyblue.java.spring.security.security03.filter;

import com.dailyblue.java.spring.security.security03.bean.Powers;
import com.dailyblue.java.spring.security.security03.config.JwtConfig;
import com.dailyblue.java.spring.security.security03.mapper.PowersMapper;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class CheckIsLoginFilter extends BasicAuthenticationFilter {
    private AuthenticationManager authenticationManager;
    private RedisTemplate redisTemplate;
    private PowersMapper powersMapper;

    public CheckIsLoginFilter(AuthenticationManager authenticationManager, RedisTemplate redisTemplate, PowersMapper powersMapper) {
        super(authenticationManager);
        this.authenticationManager = authenticationManager;
        this.redisTemplate = redisTemplate;
        this.powersMapper = powersMapper;
    }

    /*
    验证用户是否登陆
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("进入验证用户是否登陆的过滤器");
        // 接收用户传递过来的token
        String token = request.getHeader("token");
        log.info("用户传递的token是：{}", token);
        if (token != null) {
            // 判断token是否合法
            Claims claims = JwtConfig.parseJWT(token);
            Object obj = claims.get("id");
            if (obj != null) {
                String id = obj.toString();
                log.info("当前用户id:{}", id);
                Object result = redisTemplate.opsForValue().get("token:" + id);
                if (result != null) {
                    log.info("redis中身份比对成功：{}", result);
                    // 获取到用户的所有权限
                    List<Powers> list = powersMapper.findPowersByUserId(Integer.parseInt(id));
                    List<SimpleGrantedAuthority> list1 = new ArrayList<>();
                    for (Powers powers : list) {
                        SimpleGrantedAuthority s = new SimpleGrantedAuthority(powers.getUrl());
                        list1.add(s);
                    }
                    UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(id, token, list1);
                    log.info("封装后的信息是：{}", upat);
                    // 这个代表用户可以验证通过了
                    // 有权限，则放入权限上下文中
                    SecurityContextHolder.getContext().setAuthentication(upat);
                }
            }
        }
        chain.doFilter(request, response);
    }
}
